﻿using H.Utils;
using System;

namespace H.Types
{
    /// <summary>
    /// 表示一个位置
    /// </summary>
    [Serializable]
    public struct Pos
    {
        /// <summary>
        /// 一个值为空的点,其值为0,0
        /// </summary>
        public static readonly Pos Empty;

        /// <summary>
        /// 判断一个点是否为空 (为0,0)
        /// </summary>
        public bool IsEmpty => X == 0 && Y == 0;

        /// <summary>
        /// 点的横坐标
        /// </summary>
        public int X { get; set; }

        /// <summary>
        /// 点的纵坐标
        /// </summary>
        public int Y { get; set; }

        /// <summary>
        /// 初始化一个新的点
        /// </summary>
        /// <param name="x">横坐标</param>
        /// <param name="y">纵坐标</param>
        public Pos(int x, int y)
        {
            X = x;
            Y = y;
        }

        /// <summary>
        /// 初始化一个新的点
        /// </summary>
        /// <param name="point"></param>
        public Pos(string point)
        {
            int[] result = new int[2];
            if (point != null && point.SplitAsInt(2, ref result, ','))
            {
                X = result[0];
                Y = result[1];
            }
            else
            {
                X = Y = 0;
            }
        }

        /// <summary>
        /// 在当前的点上加偏移,得到一个新的点
        /// </summary>
        /// <returns></returns>
        public Pos Add(Pos offset)
        {
            offset.Offset(X, Y);
            return offset;
        }

        /// <summary>
        /// 在当前的点上加偏移,得到一个新的点
        /// </summary>
        /// <returns></returns>
        public Pos Add(int x, int y)
        {
            Pos point = this;
            point.Offset(x, y);
            return point;
        }


        /// <summary>
        /// 在当前的点上加减去偏移,得到一个新的点
        /// </summary>
        /// <returns></returns>
        public Pos Sub(Pos offset)
        {
            Pos point = this;
            point.Offset(-offset.X, -offset.Y);
            return point;
        }

        /// <summary>
        /// 在当前的点上减去偏移,得到一个新的点
        /// </summary>
        /// <returns></returns>
        public Pos Sub(int x, int y)
        {
            Pos point = this;
            point.Offset(-x, -y);
            return point;
        }

        /// <summary>
        /// 为当前点加一个偏移使之偏移到一个新的点
        /// </summary>
        /// <param name="x">偏移量X</param>
        /// <param name="y">偏移量Y</param>
        public void Offset(int x, int y)
        {
            X += x;
            Y += y;
        }

        /// <summary>
        /// 为当前点加一个偏移使之偏移到一个新的点
        /// </summary>
        /// <param name="offset">偏移量</param>
        public void Offset(Pos offset)
        {
            X += offset.X;
            Y += offset.Y;
        }

        /// <summary>
        /// 显示一个点
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return $"({X},{Y})";
        }

        /// <summary>
        /// 将Pos表示为X,Y字符串
        /// </summary>
        /// <returns></returns>
        public string MakeXY()
        {
            return $"{X},{Y}";
        }

        public override int GetHashCode()
        {
            return X ^ Y; 
        }

        public override bool Equals(object obj)
        {
            if (obj is Pos pos)
            {
                return pos.X == X && pos.Y == Y;
            } else
            {
                return false;
            }
        }
    }
}
